// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.

namespace Microsoft.Samples.Commerce.Order.CommerceEntities
{
    using Microsoft.Commerce.Contracts;

    /// <summary>
    /// Represents the credit card payment.
    /// </summary>
    public class CreditCard : PaymentAccount
    {
        /// <summary>
        /// defines the model name for this commerce entity
        /// </summary>
        public new const string ModelNameDefinition = "CreditCard";

        /// <summary>
        /// Initializes a new instance of the <see cref="CreditCard"/> class.
        /// </summary>
        public CreditCard() : base(new CommerceEntity(CreditCard.ModelNameDefinition))
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CreditCard"/> class.
        /// </summary>
        /// <param name="commerceEntity">The commerce entity.</param>
        public CreditCard(CommerceEntity commerceEntity)
            : base(commerceEntity)
        {
        }

        /// <summary>
        /// Gets or sets the credit card authorization code provided by the payment processor.
        /// </summary>
        public string AuthorizationCode
        {
            get { return this.CommerceEntity.GetPropertyValue(PropertyName.AuthorizationCode) as string; }
            set { this.CommerceEntity.SetPropertyValue(PropertyName.AuthorizationCode, value); }
        }

        /// <summary>
        /// Gets or sets the token used to identify the credit card.
        /// </summary>
        /// <remarks>Use this property to store the last four digits of the credit card number or any other token with which a user can identify the credit card he used while placing the order.</remarks>
        public string CreditCardIdentifier
        {
            get { return this.CommerceEntity.GetPropertyValue(PropertyName.CreditCardIdentifier) as string; }
            set { this.CommerceEntity.SetPropertyValue(PropertyName.CreditCardIdentifier, value); }
        }

        /// <summary>
        /// Gets or sets the credit card number.
        /// </summary>
        /// <value>The credit card number.</value>
        public string CreditCardNumber
        {
            get { return this.CommerceEntity.GetPropertyValue(PropertyName.CreditCardNumber) as string; }
            set { this.CommerceEntity.SetPropertyValue(PropertyName.CreditCardNumber, value); }
        }

        /// <summary>
        /// Gets or sets a validation code specific to the credit card vendor. For example, CVV number.
        /// </summary>
        public string ValidationCode
        {
            get { return this.CommerceEntity.GetPropertyValue(PropertyName.ValidationCode) as string; }
            set { this.CommerceEntity.SetPropertyValue(PropertyName.ValidationCode, value); }
        }

        /// <summary>
        /// Gets or sets the month that the credit card will expire.
        /// </summary>
        public int? ExpirationMonth
        {
            get
            {
                return (int?)this.CommerceEntity.GetPropertyValue(PropertyName.ExpirationMonth);
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(PropertyName.ExpirationMonth, value);
            }
        }

        /// <summary>
        /// Gets or sets the month that the credit card will expire.
        /// </summary>
        public int? ExpirationYear
        {
            get
            {
                return (int?)this.CommerceEntity.GetPropertyValue(PropertyName.ExpirationYear);
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(PropertyName.ExpirationYear, value);
            }
        }

        #region Implicit operators
        /// <summary>
        /// Performs an implicit conversion from <see cref="Microsoft.Commerce.Contracts.CommerceEntity"/> to <see cref="CreditCard"/>.
        /// </summary>
        /// <param name="commerceEntity">The commerce entity.</param>
        /// <returns>The result of the conversion.</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "Design decision for API")]
        public static implicit operator CreditCard(CommerceEntity commerceEntity)
        {
            System.Diagnostics.Debug.Assert(CreditCard.ModelNameDefinition.Equals(commerceEntity.ModelName), "Unexpected model name");
            return new CreditCard(commerceEntity);
        }
        #endregion

        /// <summary>
        /// Names of the properties exposed by this commerce entity.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Needed for external access"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Justification = "Cannot make it private as it cannot be derived from")]
        public new class PropertyName : PaymentAccount.PropertyName
        {
            /// <summary>
            /// The name of the AuthorizationCode property for a CreditCard.
            /// </summary>
            public const string AuthorizationCode = "AuthorizationCode";

            /// <summary>
            /// The name of the CreditCardIdentifier property for a CreditCard.
            /// </summary>
            public const string CreditCardIdentifier = "CreditCardIdentifier";

            /// <summary>
            /// The name of the CreditCardNumber property for a CreditCard.
            /// </summary>
            public const string CreditCardNumber = "CreditCardNumber";

            /// <summary>
            /// The name of the ValidationCode property for a CreditCard.
            /// </summary>
            public const string ValidationCode = "ValidationCode";

            /// <summary>
            /// The name of the ExpirationMonth property for CreditCard.
            /// </summary>
            public const string ExpirationMonth = "ExpirationMonth";

            /// <summary>
            /// The name of the ExpirationYear property for CreditCard.
            /// </summary>
            public const string ExpirationYear = "ExpirationYear";
        }
    }
}
